/**
 * Project: yui3-common-hub-core
 * Class RelectionParseHandler
 * Version 1.0
 * File Created at 2020-12-17
 * $Id$
 * author yuyi
 * email 1060771195@qq.com
 */
package yui.comn.hub.data.parser.handler.impl;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import yui.comn.hub.data.parser.handler.AbstractHubDataParseHandler;
import yui.comn.hub.model.HubJavaType;
import yui.comn.hub.utils.HubStringUtils;

/**
 * <p>
 * 反射获取对象数据
 * </p>
 *
 * @author yuyi (1060771195@qq.com)
 */
@Service
public class ReflectionParseHandler extends AbstractHubDataParseHandler {

    public static final String REG_NAME = "class";
    

    @Override
    protected String getRegisterName() {
        return REG_NAME;
    }
    
    @Override
    public Object dataParse(Object obj) {
        return obj;
    }

    @Override
    protected Object getObjByAttr(Object obj, String attrName) {
        try {
            Class<?> clazz = obj.getClass();
            Method method = clazz.getMethod(HubStringUtils.getGetMethodName(attrName));
            return method.invoke(obj);
        } catch (Exception e) {
            String errMsg = "获取方法值失败, methodName=" + HubStringUtils.getGetMethodName(attrName);
            log.error(errMsg, e);
            throw new RuntimeException(errMsg, e);
        }
    }


    @Override
    protected Object getAttrValue(Object obj, String attrName) {
        String methodName = null;
        try {
            Class<?> clazz = obj.getClass();
            Field field = getField(clazz, attrName, 3);
            
            //如果是boolean类型, method名称前缀是is, 比如child, 该类型是boolean, 那么获取该属性值的方法是 isChild
            if (StringUtils.equals(field.getType().getName(), HubJavaType.TYPE_BASE_BOOLEAN.getName())) {
                methodName = HubStringUtils.getIsMethodName(attrName);
            } else {
                methodName = HubStringUtils.getGetMethodName(attrName);
            }
            Method method = clazz.getMethod(methodName);
            return method.invoke(obj);
        } catch (Exception e) {
            String errMsg = "获取方法值失败, attrName=" +  attrName + ", methodName=" + methodName;
            log.error(errMsg, e);
            throw new RuntimeException(errMsg, e);
        }
    }
    
    private Field getField(Class<?> clazz, String fieldName, int retry) {
        Field field = null;
        try {
            field = clazz.getDeclaredField(fieldName);
        } catch (Exception e) {
            field = getField(clazz.getSuperclass(), fieldName, --retry);
        }
        return field;
    }
    
}
